<?php
// +----------------------------------------------------------------------
// | QSCMS
// +----------------------------------------------------------------------
// | Copyright (c)  2025 https://www.qqss.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed QSCMS is not free software, commercial use must purchase official license from official website to avoid unnecessary legal disputes.
// +----------------------------------------------------------------------
// | Author: Contract 990504246@qq.com
// +----------------------------------------------------------------------

namespace app\service\goods;

use app\common\model\GoodsCategory;
use app\common\model\GoodsSpec;

class CategoryService
{
    /**
     * 添加或编辑分类
     */
    public function saveCategory($data)
    {
        try {
            // 检查名称是否为空
            if (empty($data['name'])) {
                throw new \Exception('分类名称不能为空');
            }

            if (isset($data['id']) && $data['id']) {
                $category = GoodsCategory::findOrFail($data['id']);
            } else {
                $category = new GoodsCategory;
            }

            // 如果设置了规格，验证规格是否存在
            if (!empty($data['spec_id'])) {
                $spec = GoodsSpec::find($data['spec_id']);
                if (!$spec) {
                    throw new \Exception('关联的规格不存在');
                }
            }

            // 排序为空时 自动排序
            if (empty($data['sort'])) {
                $data['sort'] = GoodsCategory::max('sort') + 1;
            }


            $category->save($data);

            return $category;
        } catch (\Exception $e) {
            throw new \Exception('保存分类失败: ' . $e->getMessage());
        }
    }

    /**
     * 删除分类
     */
    public function deleteCategory($id)
    {
        try {
            $category = GoodsCategory::findOrFail($id);

            // 检查是否有子分类
            $child_count = GoodsCategory::where('pid', $id)->count();
            if ($child_count > 0) {
                throw new \Exception('该分类下有子分类，无法删除');
            }

            // 检查分类下是否有商品
            $goods_count = \app\common\model\Goods::where('cate_id', $id)->count();
            if ($goods_count > 0) {
                throw new \Exception('该分类下有商品，无法删除');
            }

            return $category->delete();
        } catch (\Exception $e) {
            throw new \Exception('删除分类失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取分类的规格筛选字段
     */
    public function getCategorySpecFilter($cate_id)
    {
        try {
            $cate = GoodsCategory::findOrFail($cate_id);

            // 如果分类不允许规格筛选或未关联规格，返回空数组
            if (!$cate->is_spec_filter || !$cate->spec_id) {
                return [];
            }

            // 获取规格信息
            $spec = GoodsSpec::find($cate->spec_id);
            if (!$spec) {
                return [];
            }

            // 提取可用于筛选的字段（select类型）
            $fields     = [];
            $rule_value = $spec->getData('rule_value');
            foreach ($rule_value as $field) {
                if ($field['type'] == 'select' && !empty($field['detail'])) {
                    $fields[] = [
                        'spec_id'     => $spec->getData('id'),
                        'spec_name'   => $spec->getData('name'),
                        'field_name'  => $field['value'],
                        'field_label' => $field['label'],
                        'options'     => $field['detail']
                    ];
                }
            }

            return $fields;
        } catch (\Exception $e) {
            throw new \Exception('获取分类规格筛选字段失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取分类的规格信息
     */
    public function getCategorySpec($cate_id)
    {
        try {
            $cate = GoodsCategory::findOrFail($cate_id);

            if (!$cate->spec_id) {
                return null;
            }

            return GoodsSpec::find($cate->spec_id);
        } catch (\Exception $e) {
            throw new \Exception('获取分类规格信息失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取分类树形结构
     */
    public function getCategoryTree()
    {
        try {
            return $this->getChildrenTree(0);
        } catch (\Exception $e) {
            throw new \Exception('获取分类树失败: ' . $e->getMessage());
        }
    }

    /**
     * 递归获取子分类
     */
    private function getChildrenTree($parentId)
    {
        $children = GoodsCategory::where('pid', $parentId)
            ->order('sort desc, id desc')
            ->select()
            ->map(function ($child) {
                return [
                    'value'    => $child->getData('id'),
                    'label'    => $child->getData('name'),
                    'children' => $this->getChildrenTree($child->getData('id')) // 递归获取下级分类
                ];
            });

        return $children->toArray();
    }

    /**
     * 获取带商品统计的分类树
     */
    public function getCategoryTreeWithGoods()
    {
        try {
            // 只获取顶级分类
            $topCategories = GoodsCategory::where('pid', 0)
                ->order('sort desc, id desc')
                ->select();

            $result = [];
            foreach ($topCategories as $category) {
                $item = [
                    'id'             => $category->getData('id'),
                    'pid'            => $category->getData('pid'),
                    'name'           => $category->getData('name'),
                    'spec_id'        => $category->getData('spec_id'),
                    'is_spec_filter' => $category->getData('is_spec_filter'),
                    'sort'           => $category->getData('sort'),
                    'status'         => $category->getData('status'),
                    'goods_count'    => $category->goods()->count(),
                    'children'       => $this->getChildrenWithGoods($category->getData('id')),
                    'create_time'    => $category->create_time,
                    'update_time'    => $category->update_time,
                    'pic'            => $category->getData('pic'),
                ];

                if ($category->getData('spec_id')) {
                    $spec = GoodsSpec::find($category->getData('spec_id'));
                    if ($spec) {
                        $item['spec_name'] = $spec->getData('name');
                    }
                }

                $result[] = $item;
            }

            return $result;
        } catch (\Exception $e) {
            throw new \Exception('获取分类树失败: ' . $e->getMessage());
        }
    }

    /**
     * 递归获取子分类（带商品统计）
     */
    private function getChildrenWithGoods($parentId)
    {
        $children = GoodsCategory::where('pid', $parentId)
            ->order('sort desc, id desc')
            ->select();

        $result = [];
        foreach ($children as $child) {
            $item = [
                'id'             => $child->getData('id'),
                'pid'            => $child->getData('pid'),
                'name'           => $child->getData('name'),
                'spec_id'        => $child->getData('spec_id'),
                'is_spec_filter' => $child->getData('is_spec_filter'),
                'sort'           => $child->getData('sort'),
                'status'         => $child->getData('status'),
                'goods_count'    => $child->goods()->count(),
                'children'       => $this->getChildrenWithGoods($child->getData('id')),
                'create_time'    => $child->create_time,
                'update_time'    => $child->update_time,
                'pic'            => $child->getData('pic'),
            ];

            if ($child->getData('spec_id')) {
                $spec = GoodsSpec::find($child->getData('spec_id'));
                if ($spec) {
                    $item['spec_name'] = $spec->getData('name');
                }
            }

            $result[] = $item;
        }

        return $result;
    }

    /**
     * 获取分类详情
     */
    public function getCategoryDetail($id)
    {
        try {
            $cate = GoodsCategory::with(['spec'])->find($id);

            if (!$cate) {
                throw new \Exception('分类不存在');
            }

            return $cate;
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 更新分类状态
     */
    public function updateCategoryStatus($id, $field, $value)
    {
        try {
            $cate = GoodsCategory::findOrFail($id);
            return $cate->save([$field => $value]);
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 切换分类菜单状态
     * @param int $id 分类ID
     * @return bool
     */
    public function toggleCategoryMenu($id)
    {
        try {
            // 验证分类是否存在
            $category = $this->validateCategory($id);

            // 切换菜单状态
            $category->is_menu = $category->is_menu ? 0 : 1;

            return $category->save();
        } catch (\Exception $e) {
            throw new \Exception('切换分类菜单状态失败: ' . $e->getMessage());
        }
    }

    /**
     * 验证分类是否存在
     * @param int $id 分类ID
     * @return GoodsCategory
     */
    private function validateCategory($id)
    {
        $category = GoodsCategory::find($id);
        if (!$category) {
            throw new \Exception('分类不存在');
        }
        return $category;
    }

    /**
     * 获取分类页面可用模板列表
     * @return array
     */
    public function getCategoryTemplateList()
    {
        try {
            // 获取模板目录
            $currentTemplate = config('site.theme.template', 'default');
            $templatePath    = base_path() . '/app/web/view/' . $currentTemplate . '/goods/category/';

            // 检查目录是否存在
            if (!is_dir($templatePath)) {
                return [];
            }

            // 获取所有模板文件
            $files     = scandir($templatePath);
            $templates = [];

            foreach ($files as $file) {
                // 只处理category-*.html格式的文件
                if (preg_match('/^category-(.+)\.html$/', $file, $matches)) {
                    $templateName = 'goods/category/' . str_replace('.html', '', $file);
                    $displayName  = ucfirst(str_replace('-', ' ', $matches[1]));

                    $templates[] = [
                        'value' => $templateName,
                        'label' => $displayName . ' 模板'
                    ];
                }
            }

            return $templates;
        } catch (\Exception $e) {
            throw new \Exception('获取模板列表失败: ' . $e->getMessage());
        }
    }
}